/**
 * Copyright(c) 2013 Jade Techonologies Co., Ltd.
 *
 * History:
 *   14-7-30 下午1:16 Created by dwzhang
 */
package com.jade.framework.base.comm.netty;

import java.util.List;

import com.jade.framework.base.comm.*;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

/**
 * 客户端的Inbound Handler.
 *
 * @author dwzhang
 * @version 1.0 14-7-30 下午1:16
 */
public class ClientInboundHandler extends ChannelInboundHandlerAdapter
{
    protected Protocol protocol;
    protected NettyClient client;

    public ClientInboundHandler(NettyClient client, Protocol protocol)
    {
        this.client = client;
        this.protocol = protocol;
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx)
            throws Exception
    {
        //client中已经做了处理。do nothing
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx)
            throws Exception
    {
        ProtocolSession session = client.getSession(ctx.channel());
        if (session != null && protocol.getProtocolHandler() != null) {
            protocol.getProtocolHandler().disconnected(session);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
            throws Exception
    {
        ProtocolSession session = client.getSession(ctx.channel());
        if (session != null) {
            ProtocolHandler protocolHandler = protocol.getProtocolHandler();
            if (protocolHandler != null) {
                protocolHandler.caught(session, cause);
            }
            else {
                if (ctx.channel().isActive()) {
                    ctx.close();
                }
            }
        }
        else {
            protocol.getLog().warn("An unexpected error occur:", cause);
            if (ctx.channel().isActive()) {
                ctx.close();
            }
        }
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception
    {
        ProtocolSession session = client.getSession(ctx.channel());
        ProtocolTransport transport = session.getTransport();
        ProtocolHandler protocolHandler = session.getProtocol().getProtocolHandler();
        if (msg instanceof List) {
            List listData = (List)msg;
            for (Object obj : listData) {
                if (obj instanceof ExchangeMessage) {
                    if (((ExchangeMessage)obj).isResponse()) {
                        transport.onResponse((ResponseMessage)obj);
                    }
                    else {
                        protocolHandler.received(session, obj);
                    }
                }
            }
        }
        else {
            if (msg instanceof ResponseMessage) {
                transport.onResponse((ResponseMessage)msg);
            }
            else {
                protocolHandler.received(session, msg);
            }
        }
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx)
            throws Exception
    {
        ctx.flush();
    }
}